package com.xique.park.service.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xique.common.core.constant.Constants;
import com.xique.common.core.domain.R;
import com.xique.common.core.enums.MngTypeEnum;
import com.xique.common.core.utils.DateUtils;
import com.xique.common.core.utils.SecurityUtils;
import com.xique.common.core.utils.StringUtils;
import com.xique.common.core.web.domain.AjaxResult;
import com.xique.common.core.web.domain.PageResult;
import com.xique.park.bean.domain.ParkCar;
import com.xique.park.bean.domain.ParkCarMngtype;
import com.xique.park.bean.domain.ParkGarage;
import com.xique.park.bean.dto.ParkUserDTO;
import com.xique.park.bean.request.app.ParkCarAddRequest;
import com.xique.park.bean.request.web.parkcar.BlackCarRequest;
import com.xique.park.bean.request.web.parkcar.ParkCarRequest;
import com.xique.park.bean.search.app.ParkCarListSearch;
import com.xique.park.bean.search.app.ParkUserListSearch;
import com.xique.park.bean.vo.app.ParkCarVo;
import com.xique.park.mapper.ParkCarMapper;
import com.xique.park.service.biz.service.IParkUserBizService;
import com.xique.park.service.command.service.IParkCarCommandService;
import com.xique.park.service.service.IParkCarMngtypeService;
import com.xique.park.service.service.IParkCarService;
import com.xique.park.service.service.IParkGarageService;
import com.xique.park.service.service.ParkUpdateCarLogService;
import com.xique.system.api.RemoteSystemUserService;
import com.xique.system.api.dto.OperateDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 车辆Service业务层处理
 *
 * @author xique
 * @date 2021-12-09
 */
@Slf4j
@Service
public class ParkCarServiceImpl implements IParkCarService {

    @Autowired
    private ParkCarMapper parkCarMapper;

    @Autowired
    private IParkUserBizService parkUserBizService;

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    @Autowired
    private RemoteSystemUserService remoteSystemUserService;

    @Autowired
    private IParkCarCommandService parkCarCommandService;

    @Autowired
    private IParkGarageService parkGarageService;

    @Autowired
    private IParkCarMngtypeService parkCarMngtypeService;

    @Autowired
    private ParkUpdateCarLogService parkUpdateCarLogService;

    /**
     * 查询车辆
     *
     * @param id 车辆ID
     * @return 车辆
     */
    @Override
    public ParkCar selectParkCarById(Long id) {
        return parkCarMapper.selectById(id);
    }

    /**
     * 查询车辆列表
     *
     * @param parkCar 车辆
     * @return 车辆
     */
    @Override
    public List<ParkCar> selectParkCarList(ParkCar parkCar) {
        LambdaQueryWrapper<ParkCar> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(parkCar.getId() != null, ParkCar::getId, parkCar.getId());
        wrapper.eq(null != parkCar.getParkId(), ParkCar::getParkId, parkCar.getParkId());
        wrapper.like(StrUtil.isNotBlank(parkCar.getPlate()), ParkCar::getBindPlates, parkCar.getPlate());
        wrapper.eq(StrUtil.isNotBlank(parkCar.getSeatNo()), ParkCar::getSeatNo, parkCar.getSeatNo());
        wrapper.like(StrUtil.isNotBlank(parkCar.getUserName()), ParkCar::getUserName, parkCar.getUserName());
        wrapper.like(StrUtil.isNotBlank(parkCar.getAddress()), ParkCar::getAddress, parkCar.getAddress());
        wrapper.like(StrUtil.isNotBlank(parkCar.getPhone()), ParkCar::getPhone, parkCar.getPhone());
        wrapper.eq(StrUtil.isNotBlank(parkCar.getMngType()), ParkCar::getMngType, parkCar.getMngType());
        wrapper.eq(parkCar.getParkUserId() != null, ParkCar::getParkUserId, parkCar.getParkUserId());
        // 截止日期小于当前时间
        wrapper.lt(parkCar.getEndDate() != null, ParkCar::getEndDate, parkCar.getEndDate());
        return parkCarMapper.selectList(wrapper);
    }

    /**
     * 1、如果是车辆表里面的信息，直接查询车辆表；
     * 2、如果是车主姓名，查询base_user表，然后根据查出的id，连表查询t_user表，获取到user的id，然后id作为park_user_id
     */
    @Override
    public IPage<ParkCar> selectParkCarPage(ParkCarListSearch search) {
        QueryWrapper<ParkCar> wrapper = new QueryWrapper<>();
        wrapper.eq(null != search.getParkId(), "park_id", search.getParkId());
        wrapper.like(StringUtils.isNotEmpty(search.getPlate()), "bind_plates", search.getPlate());
        wrapper.eq(null != search.getMngTypeId(), "mng_type_id", search.getMngTypeId());
        wrapper.like(StringUtils.isNotEmpty(search.getSeatNo()), "seat_no", search.getSeatNo());
        wrapper.like(StringUtils.isNotEmpty(search.getParam()), "bind_plates", search.getParam());
        if (StringUtils.isNotEmpty(search.getUserName()) || StringUtils.isNotEmpty(search.getPhone()) || StringUtils.isNotEmpty(search.getAddress()) || StringUtils.isNotEmpty(search.getParam())) {
            ParkUserListSearch userSearch = new ParkUserListSearch();
            userSearch.setParkId(search.getParkId());
            userSearch.setUserName(search.getUserName());
            userSearch.setAddress(search.getAddress());
            userSearch.setPhone(search.getPhone());
            userSearch.setParam(search.getParam());
            List<ParkUserDTO> parkUserDTOList = parkUserBizService.getParkUserIdList(userSearch);
            List<Long> parkUserIdList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(parkUserDTOList)) {
                parkUserIdList = parkUserDTOList.stream().map(ParkUserDTO::getParkUserId).collect(Collectors.toList());
                if (StringUtils.isEmpty(search.getParam())) {
                    wrapper.isNotNull("park_user_id").in("park_user_id", parkUserIdList);
                } else {
                    wrapper.or().in("park_user_id", parkUserIdList);
                }
            } else {
                //如果用户查出来是空的，param不为空，则不过滤user
                if (StringUtils.isEmpty(search.getParam())) {
                    parkUserIdList.add(-1L);
                    wrapper.isNotNull("park_user_id").in("park_user_id", parkUserIdList);
                }
            }
        }
        /* 分页处理*/
        Page<ParkCar> page = new Page<>();
        if (null != search.getPageNum() && null != search.getPageSize()) {
            page.setCurrent(search.getPageNum());
            page.setSize(search.getPageSize());
        }
        wrapper.orderByDesc("update_time");
        return parkCarMapper.selectPage(page, wrapper);
    }

    /**
     * 新增车辆
     *
     * @param parkCar 车辆
     * @return 结果
     */
    @Override
    public int insertParkCar(ParkCar parkCar) {
        parkCar.setCreateTime(DateUtils.getNowDate());
        return parkCarMapper.insert(parkCar);
    }

    /**
     * 修改车辆
     *
     * @param parkCar 车辆
     * @return 结果
     */
    @Override
    public int updateParkCar(ParkCar parkCar) {
        parkCar.setUpdateTime(DateUtils.getNowDate());
        return parkCarMapper.updateById(parkCar);
    }

    /**
     * 批量删除车辆
     *
     * @param ids 需要删除的车辆ID
     * @return 结果
     */
    @Override
    public int deleteParkCarByIds(List<Long> ids) {
        return parkCarMapper.deleteBatchIds(ids);
    }

    /**
     * 删除车辆信息
     *
     * @param id 车辆ID
     * @return 结果
     */
    @Override
    public int deleteParkCarById(Long id) {
        return parkCarMapper.deleteById(id);
    }

    @Override
    public ParkCar checkParkPlateUnique(ParkCar parkCar) {
        return parkCarMapper.checkParkPlateUnique(parkCar);
    }

    @Override
    public int batchInsert(List<ParkCar> list) {
        return parkCarMapper.insertBatch(list);
    }

    @Override
    public int batchUpdate(List<ParkCar> list) {
        return parkCarMapper.updateBatch(list);
    }

    @Override
    public List<ParkCar> selectBatchIds(List<Long> ids) {
        return parkCarMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult selectPageList(ParkCarRequest parkCarRequest) {
        Page<ParkCarVo> page = new Page<>();
        page.setCurrent(parkCarRequest.getPageNum());
        page.setSize(parkCarRequest.getPageSize());
        IPage<ParkCarVo> pageResult = parkCarMapper.selectParkCarPageList(page, parkCarRequest);
        List<ParkCarVo> parkCarVoList = pageResult.getRecords();
        if (CollUtil.isNotEmpty(parkCarVoList)) {
            parkCarVoList.forEach(parkCarVo -> {
                String bindPlates = parkCarVo.getBindPlates();
                if (StringUtils.isNotEmpty(bindPlates)) {
                    int carCnt = bindPlates.split(",").length;
                    parkCarVo.setCarCnt(carCnt);
                } else {
                    parkCarVo.setCarCnt(0);
                }
            });
        }
        long totalPages = pageResult.getPages();
        long totalSize = pageResult.getTotal();

        return PageResult.builder()
                .pageNum(parkCarRequest.getPageNum())
                .pageSize(parkCarRequest.getPageSize())
                .totalPages(totalPages)
                .totalSize(totalSize)
                .list(parkCarVoList)
                .build();
    }

    @Override
    public PageResult selectParkCarMultPageList(ParkCarRequest request) {
        Page<ParkCarVo> page = new Page<>();
        page.setCurrent(request.getPageNum());
        page.setSize(request.getPageSize());

        IPage<ParkCarVo> pageResult = parkCarMapper.selectParkCarMultPageList(page, request);
        List<ParkCarVo> parkCarVoList = pageResult.getRecords();
        if (CollUtil.isNotEmpty(parkCarVoList)) {
            parkCarVoList.forEach(parkCarVo -> {
                String bindPlates = parkCarVo.getBindPlates();
                if (StringUtils.isNotEmpty(bindPlates)) {
                    int carCnt = bindPlates.split(",").length;
                    parkCarVo.setCarCnt(carCnt);
                } else {
                    parkCarVo.setCarCnt(0);
                }
            });
        }
        long totalPages = pageResult.getPages();
        long totalSize = pageResult.getTotal();

        return PageResult.builder()
                .pageNum(request.getPageNum())
                .pageSize(request.getPageSize())
                .totalPages(totalPages)
                .totalSize(totalSize)
                .list(parkCarVoList)
                .build();
    }

    @Override
    public void batchUpdateList(List<ParkCar> parkCarList) {
        long startTime = System.currentTimeMillis();
        SqlSession sqlSession = null;
        try {
            sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
            ParkCarMapper parkCarMapper = sqlSession.getMapper(ParkCarMapper.class);
            parkCarList.forEach(parkCarMapper::updateById);
            sqlSession.commit();
            sqlSession.clearCache();
        } catch (Exception e) {
            log.info("车辆服务：批量更新异常，异常信息：{}", e.getMessage());
            e.printStackTrace();
            if (sqlSession != null) {
                sqlSession.rollback();
            }
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
        log.info("车辆服务：批量更新耗时：{}毫秒", System.currentTimeMillis() - startTime);
    }

    @Override
    public void batchInsertList(List<ParkCar> parkCarList) {
        long startTime = System.currentTimeMillis();
        SqlSession sqlSession = null;
        try {
            sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
            ParkCarMapper parkCarMapper = sqlSession.getMapper(ParkCarMapper.class);
            parkCarList.forEach(parkCarMapper::insert);
            sqlSession.commit();
            sqlSession.clearCache();
        } catch (Exception e) {
            log.info("车辆服务：批量新增异常，异常信息：{}", e.getMessage());
            e.printStackTrace();
            if (sqlSession != null) {
                sqlSession.rollback();
            }
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
        log.info("车辆服务：批量新增耗时：{}毫秒", System.currentTimeMillis() - startTime);
    }

    @Override
    public PageResult selectListByMngType(ParkCarRequest request) {
        Page<ParkCarVo> page = new Page<>();
        page.setCurrent(request.getPageNum());
        page.setSize(request.getPageSize());
        IPage<ParkCarVo> pageResult = parkCarMapper.selectListByMngType(page, request);
        List<ParkCarVo> parkCarVoList = pageResult.getRecords();

        if (CollUtil.isNotEmpty(parkCarVoList)) {
            StringBuilder operateIds = new StringBuilder();
            parkCarVoList.forEach(parkCarVo -> {
                // 组装生效时间
                Date endTime = parkCarVo.getEndDate();
                String endTimeStr = DateUtil.format(endTime, DatePattern.NORM_DATE_PATTERN);
                if (StrUtil.equals(endTimeStr, Constants.FOREVER_DATE)) {
                    parkCarVo.setTakeEffectTime(Constants.FOREVER_STR);
                } else {
                    Date beginTime = parkCarVo.getBeginDate();
                    String beginTimeStr = DateUtil.format(beginTime, DatePattern.NORM_DATE_PATTERN);
                    parkCarVo.setTakeEffectTime(beginTimeStr + "至" + endTimeStr);
                }

                // 赋值拉黑前的管理类型
                String oldMngType = parkCarVo.getOldMngType();
                if (StrUtil.isNotBlank(oldMngType)) {
                    String oldMngTypeName = MngTypeEnum.matchType(oldMngType);
                    parkCarVo.setOldMngTypeName(oldMngTypeName);
                }

                // 组装操作人ID信息
                if (parkCarVo.getUpdateUser() == null) {
                    parkCarVo.setUpdateUser(1L);
                }
                operateIds.append(parkCarVo.getUpdateUser()).append(",");
            });

            // 赋值操作人
            R<List<OperateDTO>> updateUserResult = remoteSystemUserService.getOperateList(operateIds.toString());
            if (null != updateUserResult.getData()) {
                List<OperateDTO> operateDTOList = updateUserResult.getData();
                if (CollUtil.isNotEmpty(operateDTOList)) {
                    Map<Long, String> operateMap = operateDTOList.stream().collect(Collectors.toMap(OperateDTO::getOperateId, OperateDTO::getOperateName));
                    parkCarVoList.forEach(payOrderVo -> payOrderVo.setUpdateBy(operateMap.get(payOrderVo.getUpdateUser())));
                }
            }
        }

        long totalPages = pageResult.getPages();
        long totalSize = pageResult.getTotal();

        return PageResult.builder()
                .pageNum(request.getPageNum())
                .pageSize(request.getPageSize())
                .totalPages(totalPages)
                .totalSize(totalSize)
                .list(parkCarVoList)
                .build();
    }

    @Override
    public AjaxResult saveBlackCar(BlackCarRequest request) {
        Long id = request.getId();
        parkUpdateCarLogService.generateAddBlackParkLog(request);
        if (id == null) {
            // 新增
            return addBlackCar(request);
        } else {
            // 更新
            return updateBlackCar(request);
        }
    }

    @Override
    public List<ParkCar> selectEnableCarList(String mngType, String beginDate) {
        return parkCarMapper.selectEnableCarList(mngType, beginDate);
    }

    private AjaxResult addBlackCar(BlackCarRequest request) {
        // 根据车牌号查询车辆信息
        long parkId = request.getParkId();
        String plate = request.getPlate();
        List<ParkCar> carInDbList = selectListByBindPlates(parkId, plate);
        if (CollUtil.isNotEmpty(carInDbList)) {
            if (StrUtil.equals(carInDbList.get(0).getMngType(), MngTypeEnum.BLACKLIST.getType())) {
                return AjaxResult.error("该车辆已被拉黑");
            }
            return AjaxResult.error("该车辆在车辆列表中已存在，请在车辆列表中拉黑该车辆");
        }

        // 组装车辆信息
        ParkCar parkCar = packageCarInfo(request, parkId);
        parkCarMapper.insert(parkCar);

        // 判断是否到了启用日期
        long betweenDay = DateUtil.between(parkCar.getBeginDate(), DateUtil.parseDateTime(DateUtil.now()), DateUnit.MS, false);
        if (betweenDay >= 0) {
            // 下发到设备
            return parkCarCommandService.downSingleCar(parkId, parkCar, "拉黑成功！");
        }
        return AjaxResult.success("拉黑成功！");
    }

    private ParkCar packageCarInfo(BlackCarRequest request, Long parkId) {
        ParkCar parkCar = new ParkCar();

        // 获取车库信息
        List<ParkGarage> parkGarageList = parkGarageService.selectParkGarageByParkId(parkId);
        if (CollUtil.isNotEmpty(parkGarageList)) {
            StringBuilder garageIds = new StringBuilder();
            parkGarageList.forEach(parkGarage -> garageIds.append(parkGarage.getId()).append(","));
            parkCar.setGarageIds(garageIds.toString());
        } else {
            throw new IllegalArgumentException("车库信息不存在");
        }

        // 获取管理类型信息
        List<ParkCarMngtype> parkCarMngTypeList = parkCarMngtypeService.selectListByParkIdAndMngType(parkId, MngTypeEnum.BLACKLIST.getType());
        if (CollUtil.isNotEmpty(parkCarMngTypeList)) {
            parkCar.setMngTypeId(parkCarMngTypeList.get(0).getId());
        } else {
            throw new IllegalArgumentException("黑名单管理类型不存在，请先添加黑名单管理类型");
        }

        // 判断是否永久拉黑
        if (StrUtil.equals(request.getBeginTime(), Constants.FOREVER_STR) && StrUtil.equals(request.getEndTime(), Constants.FOREVER_STR)) {
            parkCar.setBeginDate(DateUtil.parseDateTime(DateUtil.now()));
            parkCar.setEndDate(DateUtil.parseDateTime(Constants.FOREVER_TIME));
        } else {
            parkCar.setBeginDate(DateUtil.parseDateTime(request.getBeginTime()));
            parkCar.setEndDate(DateUtil.parseDateTime(request.getEndTime()));
        }

        parkCar.setParkId(SecurityUtils.getParkId());
        parkCar.setPlate(request.getPlate());
        parkCar.setBindPlates(request.getPlate());
        parkCar.setRemark(request.getRemark());
        parkCar.setMngType(MngTypeEnum.BLACKLIST.getType());
        parkCar.setSpaces(1);
        parkCar.setIsGarageSpace("N");
        parkCar.setCreateTime(new Date());
        parkCar.setCreateUser(SecurityUtils.getUserId());
        parkCar.setUpdateTime(new Date());
        parkCar.setUpdateUser(SecurityUtils.getUserId());

        return parkCar;
    }

    private List<ParkCar> selectListByBindPlates(Long parkId, String plate) {
        return parkCarMapper.selectListByBindPlates(parkId, plate);
    }

    private AjaxResult updateBlackCar(BlackCarRequest request) {
        // 根据车牌号查询车辆信息
        long parkId = request.getParkId();
        String plate = request.getPlate();
        List<ParkCar> carInDbList = selectListByBindPlates(parkId, plate);
        if (CollUtil.isNotEmpty(carInDbList) && StrUtil.equals(carInDbList.get(0).getMngType(), MngTypeEnum.BLACKLIST.getType())) {
            return AjaxResult.error("该车辆已被拉黑");
        }

        // 获取原来的车辆信息
        ParkCar oldParkCar = selectParkCarById(request.getId());
        if (null != oldParkCar) {
            // 拉黑的车辆有可能是多位多车的车辆，只拉黑当前车辆，其他车辆正常
            String oldBindPlates = oldParkCar.getBindPlates();
            String oldPlate = oldParkCar.getPlate();
            String[] oldBindPlatsArray = oldBindPlates.split(",");
            if (oldBindPlatsArray.length > 1) {
                // 多位多车的车辆
                String newBindPlates = oldBindPlates.replace("," + plate, "");
                if (StrUtil.equals(oldBindPlates, newBindPlates)) {
                    newBindPlates = oldBindPlates.replace(plate + ",", "");
                }
                oldParkCar.setBindPlates(newBindPlates);
                if (StrUtil.equals(oldPlate, plate)) {
                    oldPlate = newBindPlates.split(",")[0];
                    oldParkCar.setPlate(oldPlate);
                }

                // 新增一辆黑名单车辆的信息
                ParkCar blackParkCar = packageCarInfo(request, parkId);
                blackParkCar.setOldMngType(oldParkCar.getMngType());
                blackParkCar.setOldMngTypeId(oldParkCar.getMngTypeId());
                blackParkCar.setOldEndTime(oldParkCar.getEndDate());
                blackParkCar.setOldId(oldParkCar.getId());
                blackParkCar.setSeatNo(oldParkCar.getSeatNo());
                blackParkCar.setParkUserId(oldParkCar.getParkUserId());
                insertParkCar(blackParkCar);

                // 修改原先的车辆信息
                updateParkCar(oldParkCar);

                // 下发到设备
                parkCarCommandService.downSingleCar(parkId, oldParkCar, "");

                // 判断是否到了启用日期
                long betweenDay = DateUtil.between(blackParkCar.getBeginDate(), DateUtil.parseDateTime(DateUtil.now()), DateUnit.MS, false);
                if (betweenDay >= 0) {
                    // 下发到设备
                    return parkCarCommandService.downSingleCar(parkId, blackParkCar, "拉黑成功！");
                }
            } else {
                // 单辆车
                // 拉黑前的管理类型小类ID
                oldParkCar.setOldMngType(oldParkCar.getMngType());
                oldParkCar.setOldMngTypeId(oldParkCar.getMngTypeId());
                oldParkCar.setOldEndTime(oldParkCar.getEndDate());

                // 判断是否永久拉黑
                if (StrUtil.equals(request.getBeginTime(), Constants.FOREVER_STR) && StrUtil.equals(request.getEndTime(), Constants.FOREVER_STR)) {
                    oldParkCar.setBeginDate(DateUtil.parseDateTime(DateUtil.now()));
                    oldParkCar.setEndDate(DateUtil.parseDateTime(Constants.FOREVER_TIME));
                } else {
                    oldParkCar.setBeginDate(DateUtil.parseDateTime(request.getBeginTime()));
                    oldParkCar.setEndDate(DateUtil.parseDateTime(request.getEndTime()));
                }

                // 获取黑名单管理类型信息
                List<ParkCarMngtype> parkCarMngTypeList = parkCarMngtypeService.selectListByParkIdAndMngType(parkId, MngTypeEnum.BLACKLIST.getType());
                if (CollUtil.isNotEmpty(parkCarMngTypeList)) {
                    oldParkCar.setMngTypeId(parkCarMngTypeList.get(0).getId());
                } else {
                    throw new IllegalArgumentException("黑名单管理类型不存在，请先添加黑名单管理类型");
                }

                oldParkCar.setRemark(request.getRemark());
                oldParkCar.setMngType(MngTypeEnum.BLACKLIST.getType());
                oldParkCar.setUpdateTime(new Date());
                oldParkCar.setUpdateUser(request.getUserId());

                updateParkCar(oldParkCar);

                // 判断是否到了启用日期
                long betweenDay = DateUtil.between(oldParkCar.getBeginDate(), DateUtil.parseDateTime(DateUtil.now()), DateUnit.MS, false);
                if (betweenDay >= 0) {
                    // 下发到设备
                    return parkCarCommandService.downSingleCar(parkId, oldParkCar, "拉黑成功！");
                }

            }
            return AjaxResult.success("拉黑成功！");
        }
        return AjaxResult.error();
    }

    @Override
    public List<ParkCar> selectExportCarList(Long parkId) {
        return parkCarMapper.selectExportCarList(parkId);
    }

    @Override
    public ParkCar selectParkCarByParkIdAndPlate(Long parkId, String plate) {
        return parkCarMapper.selectParkCarByParkIdAndPlate(parkId, plate);
    }

    @Override
    public List<ParkCar> selectParkCarListByUserIds(List<Long> userIds) {
        if (CollUtil.isEmpty(userIds)) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<ParkCar> condition = Wrappers.lambdaQuery();
        condition.in(ParkCar::getParkUserId, userIds);
        return parkCarMapper.selectList(condition);
    }
}
